mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
[64111] Use Primer PageHeader in repositories (#19001)
* create a helper for breadcrumbs in repositories * move breadcrumbs to the header partial * use page header action buttons instead of toolbar items * use page header icon action buttons * add page header to revisions page * add page header to statistics page * remove breadcrumbs in annotate, changes and entry pages * change diff page * change revision page and add page header component * fix rubocup errors * fix failing tests * check breadcrumbs class in test * remove test for checking the title * fix breadcrumbs helper * add checkout instructions toggle * fix test for title check * fix Assignment Branch Condition size error * fix error while lading revision pages * remove toolbar items classes usages * use project id * move page header of revision page into a component * move page header of repository page into a component * remove toolbar classes * fix failing specs * remove toolbar usages * Re-add hook and change breadcrumb slightly * Simplify PageHeader button template * Replace custom input group with Primer component * Cleanup sass code * Correct the method for getting the "next_button" tag --------- Co-authored-by: Henriette Darge <h.darge@openproject.com>
This commit is contained in:
committed by
GitHub
parent
d4e94ae8d0
commit
8474cd8751
@@ -0,0 +1,35 @@
|
||||
<%=
|
||||
render Primer::OpenProject::PageHeader.new do |header|
|
||||
header.with_title { t(
|
||||
"repositories.named_repository",
|
||||
vendor_name: @repository.class.vendor_name
|
||||
) }
|
||||
header.with_breadcrumbs(breadcrumb_items)
|
||||
if !@empty && User.current.allowed_in_project?(:browse_repository, @project)
|
||||
header.with_action_icon_button(
|
||||
tag: :a,
|
||||
icon: :graph,
|
||||
label: t(:label_statistics),
|
||||
mobile_icon: :graph,
|
||||
mobile_label: t(:label_statistics),
|
||||
size: :medium,
|
||||
href: stats_project_repository_path(@project),
|
||||
aria: { label: t(:label_statistics) },
|
||||
title: t(:label_statistics)
|
||||
)
|
||||
end
|
||||
if User.current.allowed_in_project?(:manage_repository, @project)
|
||||
header.with_action_icon_button(
|
||||
tag: :a,
|
||||
icon: :gear,
|
||||
label: t(:label_setting_plural),
|
||||
mobile_icon: :gear,
|
||||
mobile_label: t(:label_setting_plural),
|
||||
size: :medium,
|
||||
href: project_settings_repository_path(@project),
|
||||
aria: { label: t(:label_setting_plural) },
|
||||
title: t(:label_setting_plural)
|
||||
)
|
||||
end
|
||||
end
|
||||
%>
|
||||
@@ -0,0 +1,89 @@
|
||||
# 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 Repositories
|
||||
class PageHeaderComponent < ApplicationComponent
|
||||
include ApplicationHelper
|
||||
include OpPrimer::ComponentHelpers
|
||||
|
||||
def initialize(repository:, empty: false, path: nil, rev: nil, project: nil)
|
||||
super
|
||||
@project = project
|
||||
@repository = repository
|
||||
@path = path
|
||||
@rev = rev
|
||||
@empty = empty
|
||||
end
|
||||
|
||||
def breadcrumb_items
|
||||
[
|
||||
project_breadcrumb,
|
||||
repository_breadcrumb,
|
||||
*path_breadcrumbs
|
||||
]
|
||||
end
|
||||
|
||||
def project_breadcrumb
|
||||
{
|
||||
href: project_overview_path(@project.id),
|
||||
text: @project.name
|
||||
}
|
||||
end
|
||||
|
||||
def repository_breadcrumb
|
||||
{
|
||||
href: url_for(action: "show", project_id: @project.id, repo_path: nil, rev: @rev),
|
||||
text: t("repositories.named_repository", vendor_name: @repository.class.vendor_name)
|
||||
}
|
||||
end
|
||||
|
||||
def path_breadcrumbs
|
||||
dirs = @path.to_s.split("/").compact_blank
|
||||
link_path = ""
|
||||
dirs.each_with_index.map do |dir, index|
|
||||
link_path = File.join(link_path, dir)
|
||||
|
||||
if index == dirs.size - 1
|
||||
dir
|
||||
else
|
||||
{
|
||||
href: url_for(
|
||||
action: "show",
|
||||
project_id: @project.id,
|
||||
repo_path: to_path_param(link_path),
|
||||
rev: @rev
|
||||
),
|
||||
text: dir
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,57 @@
|
||||
<%= render Primer::OpenProject::PageHeader.new do |header| %>
|
||||
<% header.with_title do %>
|
||||
<%= "#{t(:label_revision)} #{helpers.format_revision(@changeset)}" %>
|
||||
<% end %>
|
||||
|
||||
<% header.with_breadcrumbs([{
|
||||
href: project_overview_path(@project.id),
|
||||
text: @project.name
|
||||
},
|
||||
{
|
||||
href: url_for({ action: "show", project_id: @project.id }),
|
||||
text: t(
|
||||
"repositories.named_repository",
|
||||
vendor_name: @repository.class.vendor_name
|
||||
)
|
||||
},
|
||||
{
|
||||
href: revisions_project_repository_path(@project),
|
||||
text: t(:label_revision_plural)
|
||||
},
|
||||
"#{t(:label_revision)} #{helpers.format_revision(@changeset)}"
|
||||
]) %>
|
||||
|
||||
<%# Previous Revision Button %>
|
||||
<% header.with_action_button(
|
||||
tag: previous_button_tag,
|
||||
icon: "arrow-left",
|
||||
label: t(:label_previous),
|
||||
mobile_icon: "arrow-left",
|
||||
mobile_label: t(:label_previous),
|
||||
href: previous_button_url,
|
||||
disabled: previous_button_disabled?,
|
||||
title: previous_button_title,
|
||||
aria: { label: t(:label_previous) }
|
||||
) do |button|
|
||||
button.with_leading_visual_icon(icon: "arrow-left")
|
||||
t(:label_previous)
|
||||
end %>
|
||||
|
||||
<%# Next Revision Button %>
|
||||
<% header.with_action_button(
|
||||
tag: next_button_tag,
|
||||
icon: "arrow-right",
|
||||
label: t(:label_next),
|
||||
mobile_icon: "arrow-right",
|
||||
mobile_label: t(:label_next),
|
||||
href: next_button_url,
|
||||
disabled: next_button_disabled?,
|
||||
title: next_button_title,
|
||||
aria: { label: t(:label_next) }
|
||||
) do |button|
|
||||
button.with_leading_visual_icon(icon: "arrow-right")
|
||||
t(:label_next)
|
||||
end %>
|
||||
|
||||
<%# Revision Search Form Button (if needed) could go here too) %>
|
||||
<% end %>
|
||||
@@ -0,0 +1,89 @@
|
||||
# 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 Repositories
|
||||
module Revision
|
||||
class PageHeaderComponent < ApplicationComponent
|
||||
include ApplicationHelper
|
||||
include OpPrimer::ComponentHelpers
|
||||
|
||||
def initialize(changeset:, repository:, project: nil)
|
||||
super
|
||||
@project = project
|
||||
@changeset = changeset
|
||||
@repository = repository
|
||||
end
|
||||
|
||||
def previous_button_present?
|
||||
@previous_button_present ||= @changeset.previous.present?
|
||||
end
|
||||
|
||||
def next_button_present?
|
||||
@next_button_present ||= @changeset.next.present?
|
||||
end
|
||||
|
||||
def previous_button_disabled?
|
||||
!previous_button_present?
|
||||
end
|
||||
|
||||
def next_button_disabled?
|
||||
!next_button_present?
|
||||
end
|
||||
|
||||
def previous_button_url
|
||||
return nil unless previous_button_present?
|
||||
|
||||
url_for(controller: "/repositories", action: "revision", project_id: @project, rev: @changeset.previous.identifier)
|
||||
end
|
||||
|
||||
def next_button_url
|
||||
return nil unless next_button_present?
|
||||
|
||||
url_for(controller: "/repositories", action: "revision", project_id: @project, rev: @changeset.next.identifier)
|
||||
end
|
||||
|
||||
def previous_button_tag
|
||||
previous_button_present? ? :a : :button
|
||||
end
|
||||
|
||||
def next_button_tag
|
||||
next_button_present? ? :a : :button
|
||||
end
|
||||
|
||||
def previous_button_title
|
||||
previous_button_present? ? t(:label_revision_id, value: helpers.format_revision(@changeset.previous)) : t(:label_previous)
|
||||
end
|
||||
|
||||
def next_button_title
|
||||
previous_button_present? ? t(:label_revision_id, value: helpers.format_revision(@changeset.next)) : t(:label_next)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -121,7 +121,7 @@ module RepositoriesHelper
|
||||
style = +"change"
|
||||
text = File.basename(file)
|
||||
if s = tree[file][:s]
|
||||
style << " folder"
|
||||
style += " folder"
|
||||
path_param = without_leading_slash(to_path_param(@repository.relative_path(file)))
|
||||
text = link_to(h(text),
|
||||
show_revisions_path_project_repository_path(project_id: @project,
|
||||
@@ -129,10 +129,10 @@ module RepositoriesHelper
|
||||
rev: @changeset.identifier),
|
||||
title: I18n.t(:label_folder))
|
||||
|
||||
output << "<li class='#{style} icon icon-folder-#{calculate_folder_action(s)}'>#{text}</li>"
|
||||
output << render_changes_tree(s)
|
||||
output += "<li class='#{style} icon icon-folder-#{calculate_folder_action(s)}'>#{text}</li>"
|
||||
output += render_changes_tree(s)
|
||||
elsif c = tree[file][:c]
|
||||
style << " change-#{c.action}"
|
||||
style += " change-#{c.action}"
|
||||
path_param = without_leading_slash(to_path_param(@repository.relative_path(c.path)))
|
||||
|
||||
unless c.action == "D"
|
||||
@@ -156,10 +156,10 @@ module RepositoriesHelper
|
||||
|
||||
text << raw(" " + content_tag("span", h(c.from_path), class: "copied-from")) if c.from_path.present?
|
||||
|
||||
output << changes_tree_li_element(c.action, text, style)
|
||||
output += changes_tree_li_element(c.action, text, style)
|
||||
end
|
||||
end
|
||||
output << "</ul>"
|
||||
output += "</ul>"
|
||||
output.html_safe
|
||||
end
|
||||
|
||||
|
||||
@@ -1,60 +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.
|
||||
|
||||
++#%>
|
||||
|
||||
<%= link_to(
|
||||
{ action: "show", project_id: @project, repo_path: nil, rev: @rev },
|
||||
{ title: I18n.t(:label_repository_root) }
|
||||
) do %>
|
||||
<%= op_icon("icon-home repository-breadcrumbs--home") %>
|
||||
<% end %>
|
||||
<%
|
||||
dirs = path.split('/')
|
||||
link_path = ''
|
||||
dirs.each_with_index do |dir, index|
|
||||
next if dir.blank?
|
||||
link_path << '/' unless link_path.empty?
|
||||
link_path << "#{dir}"
|
||||
%>
|
||||
<span class="repository-breadcrumbs--sep"></span>
|
||||
<% if index == dirs.size - 1 %>
|
||||
<strong><%= h(dir) %></strong>
|
||||
<% else %>
|
||||
<%= link_to h(dir), action: "show", project_id: @project,
|
||||
repo_path: to_path_param(link_path), rev: @rev %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%
|
||||
# @rev is revision or git branch or tag.
|
||||
rev_text = @changeset.nil? ? @rev : format_revision(@changeset)
|
||||
%>
|
||||
<span class="repository-bradcrumbs--identifier">
|
||||
<%= "(#{t('repositories.at_identifier', identifier: rev_text)})" if rev_text.present? %>
|
||||
</span>
|
||||
|
||||
<% html_title(h(with_leading_slash(path))) -%>
|
||||
@@ -28,59 +28,55 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
++#%>
|
||||
|
||||
<opce-persistent-toggle data-identifier="repository.checkout_instructions"></opce-persistent-toggle>
|
||||
<%= toolbar title: t(
|
||||
"repositories.named_repository",
|
||||
vendor_name: @repository.class.vendor_name
|
||||
) do %>
|
||||
<% if @instructions && @instructions.available? %>
|
||||
<li class="toolbar-item toolbar-input-group hidden-for-mobile">
|
||||
<div class="toolbar-input-group--affix -prepend">
|
||||
<span><%= @instructions.checkout_command %></span>
|
||||
</div>
|
||||
<input id="repository-checkout-url"
|
||||
type="text" class="-clickable" size="40"
|
||||
value="<%= @instructions.checkout_url(true) %>"
|
||||
readonly>
|
||||
<% csp_onclick("this.focus(); this.select();", "#repository-checkout-url") %>
|
||||
<opce-copy-to-clipboard click-target=".repository-checkout-copy-button"
|
||||
clipboard-target="#repository-checkout-url">
|
||||
</opce-copy-to-clipboard>
|
||||
<button class="repository-checkout-copy-button toolbar-input--affix toolbar-input-group--affix -append"
|
||||
title="<%= t(:button_copy_to_clipboard) %>">
|
||||
<%= op_icon("icon-copy") %>
|
||||
<span class="hidden-for-sighted"><%= t(:button_copy_to_clipboard) %></span>
|
||||
</button>
|
||||
</li>
|
||||
<li class="toolbar-item -icon-only">
|
||||
<a id="repository--checkout-instructions-toggle"
|
||||
class="persistent-toggle--click-handler button"
|
||||
title="<%= t("repositories.checkout.show_instructions") %>">
|
||||
<%= op_icon("button--icon icon-info1") %>
|
||||
</a>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if !empty && User.current.allowed_in_project?(:browse_repository, @project) %>
|
||||
<li class="toolbar-item -icon-only">
|
||||
<%= link_to stats_project_repository_path(@project),
|
||||
class: "button", title: t(:label_statistics) do %>
|
||||
<%= op_icon("button--icon icon-chart1") %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
<%= call_hook(
|
||||
:repositories_navigation_toolbar,
|
||||
{ repository: @repository, project: @project, repository_empty: empty }
|
||||
) %>
|
||||
<% if User.current.allowed_in_project?(:manage_repository, @project) %>
|
||||
<li class="toolbar-item -icon-only">
|
||||
<%= link_to project_settings_repository_path(@project),
|
||||
class: "button", title: t(:label_setting_plural) do %>
|
||||
<%= op_icon("button--icon icon-settings") %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
<%= render(Repositories::PageHeaderComponent.new(repository: @repository, empty: empty, path: @path, rev: @rev, project: @project)) %>
|
||||
<% if @instructions && @instructions.available? %>
|
||||
<%=
|
||||
render(Primer::OpenProject::FlexLayout.new(align_items: :flex_end, mb: 2)) do |container|
|
||||
container.with_column(mr: 2, classes: "repository--checkout-container") do
|
||||
render(Primer::OpenProject::InputGroup.new(input_width: :large)) do |group|
|
||||
group.with_text_input(
|
||||
id: "repository-checkout-url",
|
||||
name: "repository-checkout-url",
|
||||
label: @instructions.checkout_command,
|
||||
value: @instructions.checkout_url(true),
|
||||
readonly: true
|
||||
)
|
||||
group.with_trailing_action_clipboard_copy_button(
|
||||
value: @instructions.checkout_url(true),
|
||||
aria: { label: t(:button_copy_to_clipboard) }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
container.with_column do
|
||||
render(
|
||||
Primer::Beta::IconButton.new(
|
||||
icon: :info,
|
||||
tag: :a,
|
||||
id: "repository--checkout-instructions-toggle",
|
||||
classes: "persistent-toggle--click-handler",
|
||||
aria: { label: t("repositories.checkout.show_instructions") },
|
||||
title: t("repositories.checkout.show_instructions")
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
%>
|
||||
<% end %>
|
||||
|
||||
<%= call_hook(
|
||||
:repositories_navigation_toolbar,
|
||||
{ repository: @repository, project: @project, repository_empty: empty }
|
||||
) %>
|
||||
|
||||
<%
|
||||
# @rev is revision or git branch or tag.
|
||||
rev_text = @changeset.nil? ? @rev : format_revision(@changeset)
|
||||
%>
|
||||
<span>
|
||||
<%= "(#{t('repositories.at_identifier', identifier: rev_text)})" if rev_text.present? %>
|
||||
</span>
|
||||
<% if @instructions %>
|
||||
<%= render partial: "checkout_instructions",
|
||||
locals: { repository: @repository, instructions: @instructions } %>
|
||||
|
||||
@@ -30,10 +30,6 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
<% html_title(t(:button_annotate)) %>
|
||||
<%= render partial: "repository_header", locals: { empty: false } %>
|
||||
|
||||
<div class="repository-breadcrumbs">
|
||||
<%= render partial: "breadcrumbs",
|
||||
locals: { path: @path, revision: @rev }.merge(kind: "file") %>
|
||||
</div>
|
||||
<p><%= render partial: "link_to_functions" %></p>
|
||||
|
||||
<% if @annotate.nil? || @annotate.empty? %>
|
||||
|
||||
@@ -30,11 +30,6 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
<%= call_hook(:view_repositories_show_contextual, { repository: @repository, project: @project }) %>
|
||||
<%= render partial: "repository_header", locals: { empty: false } %>
|
||||
|
||||
<div class="repository-breadcrumbs">
|
||||
<%= render partial: "breadcrumbs",
|
||||
locals: { path: @path, revision: @rev }.merge(kind: (@entry ? @entry.kind : nil)) %>
|
||||
</div>
|
||||
|
||||
<p><%= render partial: "link_to_functions" %></p>
|
||||
|
||||
<%= render_properties(@properties) %>
|
||||
|
||||
@@ -27,23 +27,42 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
|
||||
++#%>
|
||||
|
||||
<%= toolbar title: "#{t(:label_revision)} #{@diff_format_revisions} #{@path}" do %>
|
||||
<li class="toolbar-item">
|
||||
<%= form_tag({repo_path: to_path_param(@path)}, method: :get) do %>
|
||||
<%= hidden_field_tag('rev', params[:rev]) if params[:rev] %>
|
||||
<%= hidden_field_tag('rev_to', params[:rev_to]) if params[:rev_to] %>
|
||||
<%= styled_select_tag 'type', options_for_select([[t(:label_diff_inline), "inline"], [t(:label_diff_side_by_side), "sbs"]], @diff_type), id: "repository-diff-type-select" %>
|
||||
<% end %>
|
||||
<%=
|
||||
content_for(:additional_js_dom_ready) do
|
||||
"jQuery('#repository-diff-type-select').change(function() {
|
||||
<%=
|
||||
render Primer::OpenProject::PageHeader.new do |header|
|
||||
header.with_title { "#{t(:label_revision)} #{@diff_format_revisions} #{@path}" }
|
||||
header.with_breadcrumbs([{
|
||||
href: project_overview_path(@project.id),
|
||||
text: @project.name
|
||||
},
|
||||
{
|
||||
href: url_for({ action: "show", project_id: @project.id }),
|
||||
text: t(
|
||||
"repositories.named_repository",
|
||||
vendor_name: @repository.class.vendor_name
|
||||
)
|
||||
},
|
||||
{
|
||||
href: revisions_project_repository_path(@project),
|
||||
text: t(:label_revision_plural)
|
||||
},
|
||||
"#{t(:label_revision)} #{@diff_format_revisions} #{@path}"
|
||||
])
|
||||
end
|
||||
%>
|
||||
<div class="repository-input-group">
|
||||
<%= form_tag({repo_path: to_path_param(@path)}, method: :get) do %>
|
||||
<%= hidden_field_tag('rev', params[:rev]) if params[:rev] %>
|
||||
<%= hidden_field_tag('rev_to', params[:rev_to]) if params[:rev_to] %>
|
||||
<%= styled_select_tag 'type', options_for_select([[t(:label_diff_inline), "inline"], [t(:label_diff_side_by_side), "sbs"]], @diff_type), id: "repository-diff-type-select" %>
|
||||
<% end %>
|
||||
<%=
|
||||
content_for(:additional_js_dom_ready) do
|
||||
"jQuery('#repository-diff-type-select').change(function() {
|
||||
if (this.value != '') { this.form.submit() }
|
||||
});".html_safe
|
||||
end
|
||||
%>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
end
|
||||
%>
|
||||
</div>
|
||||
<% cache(@cache_key) do -%>
|
||||
<%= render partial: 'common/diff', locals: { diff: @diff, diff_type: @diff_type } %>
|
||||
<% end -%>
|
||||
|
||||
@@ -31,11 +31,6 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
|
||||
<%= render partial: "repository_header", locals: { empty: false } %>
|
||||
|
||||
<div class="repository-breadcrumbs">
|
||||
<%= render partial: "breadcrumbs",
|
||||
locals: { path: @path, revision: @rev }.merge(kind: "dir") %>
|
||||
</div>
|
||||
|
||||
<p><%= render partial: "link_to_functions" %></p>
|
||||
|
||||
<%= render partial: "common/file", locals: { filename: @path, content: @content } %>
|
||||
|
||||
@@ -27,26 +27,9 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
|
||||
++#%>
|
||||
|
||||
<%= toolbar title: "#{t(:label_revision)} #{format_revision(@changeset)}" do %>
|
||||
<li class="toolbar-item">
|
||||
<% if @changeset.previous.nil? %>
|
||||
<button class="button" disabled="disabled"><%= t(:label_previous) %></button>
|
||||
<% else %>
|
||||
<%= link_to_revision(@changeset.previous, @project, text: t(:label_previous), class: "button") %>
|
||||
<% end %>
|
||||
</li>
|
||||
<li class="toolbar-item">
|
||||
<% if @changeset.next.nil? %>
|
||||
<button class="button" disabled="disabled"><%= t(:label_next) %></button>
|
||||
<% else %>
|
||||
<%= link_to_revision(@changeset.next, @project, text: t(:label_next), class: "button") %>
|
||||
<% end %>
|
||||
</li>
|
||||
<li class="toolbar-item">
|
||||
<%= form_tag({ controller: "/repositories", action: "revision", project_id: @project }, method: :get) do %>
|
||||
<%= text_field_tag :rev, @rev, placeholder: t(:label_revision) %>
|
||||
<% end %>
|
||||
</li>
|
||||
<%= render(Repositories::Revision::PageHeaderComponent.new(changeset: @changeset, repository: @repository, project: @project)) %>
|
||||
<%= form_tag({ controller: "/repositories", action: "revision", project_id: @project }, method: :get) do %>
|
||||
<%= text_field_tag :rev, @rev, placeholder: t(:label_revision) %>
|
||||
<% end %>
|
||||
<p><% if @changeset.scmid %>ID: <%= h(@changeset.scmid) %><br>
|
||||
<% end %>
|
||||
|
||||
@@ -26,16 +26,32 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
See COPYRIGHT and LICENSE files for more details.
|
||||
|
||||
++#%>
|
||||
<%= toolbar title: t(:label_revision_plural) do %>
|
||||
<%= form_tag({ action: "revision", id: @project }, { method: :get }) do %>
|
||||
<li class="toolbar-item">
|
||||
<%= label_tag :rev, t(:label_revision), class: "hidden-for-sighted" %>
|
||||
<%= text_field_tag :rev, @rev, size: 8, placeholder: t(:label_revision) %>
|
||||
</li>
|
||||
<li class="toolbar-item">
|
||||
<%= submit_tag "OK", class: "button -primary" %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
<%=
|
||||
render Primer::OpenProject::PageHeader.new do |header|
|
||||
header.with_title { t(:label_revision_plural) }
|
||||
header.with_breadcrumbs([{
|
||||
href: project_overview_path(@project.id),
|
||||
text: @project.name
|
||||
},
|
||||
{
|
||||
href: url_for({ action: "show", project_id: @project.id }),
|
||||
text: t(
|
||||
"repositories.named_repository",
|
||||
vendor_name: @repository.class.vendor_name
|
||||
)
|
||||
},
|
||||
t(:label_revision_plural)
|
||||
])
|
||||
end
|
||||
%>
|
||||
|
||||
<%= form_tag({ action: "revision", id: @project }, { method: :get }) do %>
|
||||
<div class="revisions-action-container">
|
||||
<%= label_tag :rev, t(:label_revision), class: "hidden-for-sighted" %>
|
||||
<%= text_field_tag :rev, @rev, size: 8, placeholder: t(:label_revision) %>
|
||||
<%= submit_tag "OK", class: "button -primary" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= render partial: "revisions", locals: { project: @project, path: "", revisions: @changesets, entry: nil } %>
|
||||
<%= pagination_links_full @changesets %>
|
||||
|
||||
@@ -30,19 +30,15 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
<% content_controller "repository-navigation", dynamic: true %>
|
||||
<%= render partial: "repository_header", locals: { empty: false } %>
|
||||
|
||||
<div class="repository-breadcrumbs">
|
||||
<%= render partial: "breadcrumbs",
|
||||
locals: { path: @path, revision: @rev }.merge(kind: "dir") %>
|
||||
</div>
|
||||
|
||||
<% if !@entries.nil? && authorize_for('repositories', 'browse') %>
|
||||
<%= render partial: "dir_list" %>
|
||||
<% end %>
|
||||
|
||||
<%= render_properties(@properties) %>
|
||||
|
||||
<%= toolbar title: t(:label_revision_plural), html: { class: "repository--revision-toolbar" } do %>
|
||||
<div class="repository--revision-toolbar">
|
||||
<%# rev => nil prevents overwriting the rev parameter queried for in the form with the parameter from the request %>
|
||||
<div class="revisions-title-container"><h2><%= t(:label_revision_plural) %></h2></div>
|
||||
<%= form_tag(
|
||||
{ action: controller.action_name,
|
||||
project_id: @project,
|
||||
@@ -55,60 +51,65 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
"repository-navigation-target": "form"
|
||||
}
|
||||
) do %>
|
||||
<li class="toolbar-item toolbar-input-group hidden-for-mobile">
|
||||
<div>
|
||||
<%= label_tag "rev", I18n.t("repositories.go_to_revision") %>
|
||||
<div class="revisions-items">
|
||||
<div class="revisions-item hidden-for-mobile">
|
||||
<div class="revisions-item--label">
|
||||
<%= label_tag "rev", I18n.t("repositories.go_to_revision") %>
|
||||
</div>
|
||||
<%= text_field_tag :rev,
|
||||
@rev,
|
||||
id: "revision-identifier-input",
|
||||
class: "revisions-item--input",
|
||||
placeholder: t(:label_revision),
|
||||
data: {
|
||||
"repository-navigation-target": "revision",
|
||||
action: "keydown.enter->repository-navigation#sendForm"
|
||||
} %>
|
||||
</div>
|
||||
<%= text_field_tag :rev,
|
||||
@rev,
|
||||
id: "revision-identifier-input",
|
||||
placeholder: t(:label_revision),
|
||||
<% if !@repository.branches.nil? && @repository.branches.length > 0 %>
|
||||
<div class="revisions-item hidden-for-mobile">
|
||||
<div class="revisions-item--label">
|
||||
<%= label_tag "branch", I18n.t(:label_branch) %>
|
||||
</div>
|
||||
<%= select_tag :branch,
|
||||
options_for_select(@repository.branches, @rev),
|
||||
include_blank: "--- #{t(:actionview_instancetag_blank_option)} ---",
|
||||
id: "revision-branch-select",
|
||||
class: "revisions-item--input",
|
||||
data: {
|
||||
"repository-navigation-target": "revision",
|
||||
action: "keydown.enter->repository-navigation#sendForm"
|
||||
"repository-navigation-target": "branch",
|
||||
action: "repository-navigation#applyValue"
|
||||
} %>
|
||||
</li>
|
||||
<% if !@repository.branches.nil? && @repository.branches.length > 0 %>
|
||||
<li class="toolbar-item toolbar-input-group hidden-for-mobile">
|
||||
<div>
|
||||
<%= label_tag "branch", I18n.t(:label_branch) %>
|
||||
</div>
|
||||
<%= select_tag :branch,
|
||||
options_for_select(@repository.branches, @rev),
|
||||
include_blank: "--- #{t(:actionview_instancetag_blank_option)} ---",
|
||||
id: "revision-branch-select",
|
||||
data: {
|
||||
"repository-navigation-target": "branch",
|
||||
action: "repository-navigation#applyValue"
|
||||
} %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if !@repository.tags.nil? && @repository.tags.length > 0 %>
|
||||
<li class="toolbar-item toolbar-input-group hidden-for-mobile">
|
||||
<div>
|
||||
<%= label_tag "tag", I18n.t(:label_tag) %>
|
||||
</div>
|
||||
<%= select_tag :tag,
|
||||
options_for_select(@repository.tags, @rev),
|
||||
include_blank: "--- #{t(:actionview_instancetag_blank_option)} ---",
|
||||
id: "revision-tag-select",
|
||||
data: {
|
||||
"repository-navigation-target": "tag",
|
||||
action: "repository-navigation#applyValue"
|
||||
} %>
|
||||
</li>
|
||||
<% end %>
|
||||
<li class="toolbar-item -icon-only">
|
||||
<%= link_to(
|
||||
{ url: { action: "revision#revision-identifier-inputs", project_id: @project,
|
||||
key: User.current.rss_key } },
|
||||
{ class: "button", title: t("repositories.atom_revision_feed") }
|
||||
) do %>
|
||||
<%= op_icon("button--icon icon-export-atom") %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% if !@repository.tags.nil? && @repository.tags.length > 0 %>
|
||||
<div class="revisions-item hidden-for-mobile">
|
||||
<div class="revisions-item--label">
|
||||
<%= label_tag "tag", I18n.t(:label_tag) %>
|
||||
</div>
|
||||
<%= select_tag :tag,
|
||||
options_for_select(@repository.tags, @rev),
|
||||
include_blank: "--- #{t(:actionview_instancetag_blank_option)} ---",
|
||||
id: "revision-tag-select",
|
||||
class: "revisions-item--input",
|
||||
data: {
|
||||
"repository-navigation-target": "tag",
|
||||
action: "repository-navigation#applyValue"
|
||||
} %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="revisions-item -icon-only">
|
||||
<%= link_to(
|
||||
{ url: { action: "revision#revision-identifier-inputs", project_id: @project,
|
||||
key: User.current.rss_key } },
|
||||
{ class: "button button_no-margin", title: t("repositories.atom_revision_feed") }
|
||||
) do %>
|
||||
<%= op_icon("button--icon icon-export-atom") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% if authorize_for('repositories', 'revisions') %>
|
||||
<% if @changesets && !@changesets.empty? %>
|
||||
|
||||
@@ -27,7 +27,16 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
|
||||
++#%>
|
||||
|
||||
<%= toolbar title: t(:label_statistics) %>
|
||||
<%=
|
||||
render Primer::OpenProject::PageHeader.new do |header|
|
||||
header.with_title { t(:label_statistics) }
|
||||
header.with_breadcrumbs([{ href: project_overview_path(@project.id), text: @project.name },
|
||||
{ href: url_for({ action: "show", project_id: @project }),
|
||||
text: @repository ? t("repositories.named_repository", vendor_name: @repository.class.vendor_name) : t(:label_repository) },
|
||||
t(:label_statistics)
|
||||
])
|
||||
end
|
||||
%>
|
||||
|
||||
<p class="autoscroll">
|
||||
<%= tag(
|
||||
|
||||
@@ -191,7 +191,6 @@ import { NoResultsComponent } from 'core-app/shared/components/no-results/no-res
|
||||
import {
|
||||
OpNonWorkingDaysListComponent,
|
||||
} from 'core-app/shared/components/op-non-working-days-list/op-non-working-days-list.component';
|
||||
import { CopyToClipboardComponent } from 'core-app/shared/components/copy-to-clipboard/copy-to-clipboard.component';
|
||||
import { GlobalSearchTitleComponent } from 'core-app/core/global_search/title/global-search-title.component';
|
||||
import { PersistentToggleComponent } from 'core-app/shared/components/persistent-toggle/persistent-toggle.component';
|
||||
import { TypeFormConfigurationComponent } from 'core-app/features/admin/types/type-form-configuration.component';
|
||||
@@ -453,7 +452,6 @@ export class OpenProjectModule implements DoBootstrap {
|
||||
registerCustomElement('opce-non-working-days-list', OpNonWorkingDaysListComponent, { injector });
|
||||
registerCustomElement('opce-main-menu-toggle', MainMenuToggleComponent, { injector });
|
||||
registerCustomElement('opce-main-menu-resizer', MainMenuResizerComponent, { injector });
|
||||
registerCustomElement('opce-copy-to-clipboard', CopyToClipboardComponent, { injector });
|
||||
registerCustomElement('opce-global-search-title', GlobalSearchTitleComponent, { injector });
|
||||
registerCustomElement('opce-persistent-toggle', PersistentToggleComponent, { injector });
|
||||
registerCustomElement('opce-admin-type-form-configuration', TypeFormConfigurationComponent, { injector });
|
||||
|
||||
@@ -1,74 +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.
|
||||
//++
|
||||
|
||||
import { ChangeDetectionStrategy, Component, ElementRef, OnInit } from '@angular/core';
|
||||
import { ToastService } from 'core-app/shared/components/toaster/toast.service';
|
||||
import { I18nService } from 'core-app/core/i18n/i18n.service';
|
||||
|
||||
import { CopyToClipboardService } from './copy-to-clipboard.service';
|
||||
|
||||
@Component({
|
||||
template: '',
|
||||
selector: 'opce-copy-to-clipboard',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
|
||||
export class CopyToClipboardComponent implements OnInit {
|
||||
public clickTarget:string;
|
||||
|
||||
public clipboardTarget:string;
|
||||
|
||||
private target:JQuery;
|
||||
|
||||
constructor(
|
||||
readonly toastService:ToastService,
|
||||
readonly elementRef:ElementRef,
|
||||
readonly I18n:I18nService,
|
||||
protected copyToClipboardService:CopyToClipboardService,
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
const element = this.elementRef.nativeElement;
|
||||
// Get inputs as attributes since this is a bootstrapped directive
|
||||
this.clickTarget = element.getAttribute('click-target');
|
||||
this.clipboardTarget = element.getAttribute('clipboard-target');
|
||||
|
||||
jQuery(this.clickTarget).on('click', (evt:JQuery.TriggeredEvent) => this.onClick(evt));
|
||||
|
||||
element.classList.add('copy-to-clipboard');
|
||||
this.target = jQuery(this.clipboardTarget ? this.clipboardTarget : element);
|
||||
}
|
||||
|
||||
onClick($event:JQuery.TriggeredEvent) {
|
||||
$event.preventDefault();
|
||||
// Select the text in case the clipboard is not supported by the browser
|
||||
this.target.select().focus();
|
||||
this.copyToClipboardService.copy(String(this.target.val()));
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,6 @@ import { HomescreenNewFeaturesBlockComponent } from 'core-app/features/homescree
|
||||
import { TablePaginationComponent } from 'core-app/shared/components/table-pagination/table-pagination.component';
|
||||
import { StaticQueriesService } from 'core-app/shared/components/op-view-select/op-static-queries.service';
|
||||
import { CopyToClipboardService } from './components/copy-to-clipboard/copy-to-clipboard.service';
|
||||
import { CopyToClipboardComponent } from './components/copy-to-clipboard/copy-to-clipboard.component';
|
||||
import { OpDateTimeComponent } from './components/date/op-date-time.component';
|
||||
import { ToastComponent } from './components/toaster/toast.component';
|
||||
import { ToastsContainerComponent } from './components/toaster/toasts-container.component';
|
||||
@@ -197,9 +196,6 @@ export function bootstrapModule(injector:Injector):void {
|
||||
OPContextMenuComponent,
|
||||
IconTriggeredContextMenuComponent,
|
||||
|
||||
// Add functionality to rails rendered templates
|
||||
CopyToClipboardComponent,
|
||||
|
||||
ResizerComponent,
|
||||
|
||||
TablePaginationComponent,
|
||||
|
||||
@@ -71,29 +71,41 @@ li.change
|
||||
margin-right: 1em
|
||||
|
||||
.repository--revision-toolbar
|
||||
display: flex
|
||||
margin-top: 3rem
|
||||
|
||||
.repository--checkout-instructions--url
|
||||
margin-top: 1rem
|
||||
.repository--checkout-container
|
||||
width: 450px
|
||||
|
||||
.repository-breadcrumbs
|
||||
font-size: 0.9rem
|
||||
margin: 15px 0
|
||||
.repository-input-group
|
||||
display: flex
|
||||
|
||||
.repository-breadcrumbs--home
|
||||
font-size: 0.75rem
|
||||
.revisions-action-container
|
||||
display: flex
|
||||
gap: 0.5rem
|
||||
width: 50%
|
||||
.button
|
||||
height: 36px
|
||||
|
||||
.repository-bradcrumbs--identifier
|
||||
display: inline-block
|
||||
margin-left: 10px
|
||||
.revisions-title-container
|
||||
flex: 1 1
|
||||
white-space: nowrap
|
||||
max-width: 100%
|
||||
|
||||
.repository-breadcrumbs--sep
|
||||
display: inline-block
|
||||
margin: 0 2px
|
||||
.revisions-items
|
||||
display: flex
|
||||
gap: 0.5rem
|
||||
|
||||
&::before
|
||||
content: '▸'
|
||||
color: var(--fgColor-muted)
|
||||
.revisions-item
|
||||
display: flex
|
||||
align-items: center
|
||||
|
||||
.revisions-item--input
|
||||
flex: 1
|
||||
flex-basis: 150px
|
||||
|
||||
.revisions-item--label
|
||||
padding: 0 5px
|
||||
|
||||
table.filecontent
|
||||
border: 1px solid var(--borderColor-default)
|
||||
|
||||
@@ -244,7 +244,7 @@ RSpec.describe RepositoriesController do
|
||||
shared_examples "renders the repository title" do |active_breadcrumb|
|
||||
it do
|
||||
expect(response).to be_successful
|
||||
expect(response.body).to have_css(".repository-breadcrumbs", text: active_breadcrumb)
|
||||
expect(response.body).to have_css(".PageHeader-breadcrumbs", text: active_breadcrumb)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user