diff options
Diffstat (limited to 'app/components')
-rw-r--r-- | app/components/diffs/base_component.rb | 10 | ||||
-rw-r--r-- | app/components/diffs/overflow_warning_component.html.haml | 9 | ||||
-rw-r--r-- | app/components/diffs/overflow_warning_component.rb | 73 | ||||
-rw-r--r-- | app/components/diffs/stats_component.html.haml | 1 | ||||
-rw-r--r-- | app/components/diffs/stats_component.rb | 67 | ||||
-rw-r--r-- | app/components/pajamas/alert_component.html.haml | 13 | ||||
-rw-r--r-- | app/components/pajamas/alert_component.rb | 45 |
7 files changed, 218 insertions, 0 deletions
diff --git a/app/components/diffs/base_component.rb b/app/components/diffs/base_component.rb new file mode 100644 index 00000000000..9e1347d1e84 --- /dev/null +++ b/app/components/diffs/base_component.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Diffs + class BaseComponent < ViewComponent::Base + # To make converting the partials to components easier, + # we delegate all missing methods to the helpers, + # where they probably are. + delegate_missing_to :helpers + end +end diff --git a/app/components/diffs/overflow_warning_component.html.haml b/app/components/diffs/overflow_warning_component.html.haml new file mode 100644 index 00000000000..907d066e73d --- /dev/null +++ b/app/components/diffs/overflow_warning_component.html.haml @@ -0,0 +1,9 @@ += render Pajamas::AlertComponent.new(title: _('Too many changes to show.'), + variant: :warning, + alert_class: 'gl-mb-5') do + .gl-alert-body + = message + + .gl-alert-actions + = diff_link + = patch_link diff --git a/app/components/diffs/overflow_warning_component.rb b/app/components/diffs/overflow_warning_component.rb new file mode 100644 index 00000000000..0d0e225beb4 --- /dev/null +++ b/app/components/diffs/overflow_warning_component.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +module Diffs + class OverflowWarningComponent < BaseComponent + # Skipping coverage because of https://gitlab.com/gitlab-org/gitlab/-/issues/357381 + # + # This is fully tested by the output in the view part of this component, + # but undercoverage doesn't understand the relationship between the two parts. + # + # :nocov: + def initialize(diffs:, diff_files:, project:, commit: nil, merge_request: nil) + @diffs = diffs + @diff_files = diff_files + @project = project + @commit = commit + @merge_request = merge_request + end + + def message + html_escape(message_text) % { + display_size: @diff_files.size, + real_size: @diffs.real_size, + strong_open: '<strong>'.html_safe, + strong_close: '</strong>'.html_safe + } + end + + def diff_link + text = _("Plain diff") + + if commit? + link_to text, project_commit_path(@project, @commit, format: :diff), class: button_classes + elsif merge_request? + link_to text, merge_request_path(@merge_request, format: :diff), class: button_classes + end + end + + def patch_link + text = _("Email patch") + + if commit? + link_to text, project_commit_path(@project, @commit, format: :patch), class: button_classes + elsif merge_request? + link_to text, merge_request_path(@merge_request, format: :patch), class: button_classes + end + end + + private + + def commit? + current_controller?(:commit) && + @commit.present? + end + + def merge_request? + current_controller?("projects/merge_requests/diffs") && + @merge_request.present? && + @merge_request.persisted? + end + + def message_text + _( + "To preserve performance only %{strong_open}%{display_size} " \ + "of %{real_size}%{strong_close} files are displayed." + ) + end + + def button_classes + "btn gl-alert-action btn-default gl-button btn-default-secondary" + end + # :nocov: + end +end diff --git a/app/components/diffs/stats_component.html.haml b/app/components/diffs/stats_component.html.haml new file mode 100644 index 00000000000..c0e816639a7 --- /dev/null +++ b/app/components/diffs/stats_component.html.haml @@ -0,0 +1 @@ +.js-diff-stats-dropdown{ data: { changed: @changed, added: @added, deleted: @removed, files: diff_files_data } } diff --git a/app/components/diffs/stats_component.rb b/app/components/diffs/stats_component.rb new file mode 100644 index 00000000000..55589c7b015 --- /dev/null +++ b/app/components/diffs/stats_component.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +module Diffs + class StatsComponent < BaseComponent + attr_reader :diff_files + + def initialize(diff_files:) + @diff_files = diff_files + @changed ||= diff_files.size + @added ||= diff_files.sum(&:added_lines) + @removed ||= diff_files.sum(&:removed_lines) + end + + def diff_files_data + diffs_map = @diff_files.map do |f| + { + href: "##{helpers.hexdigest(f.file_path)}", + title: f.new_path, + name: f.file_path, + path: diff_file_path_text(f), + icon: diff_file_changed_icon(f), + iconColor: "#{diff_file_changed_icon_color(f)}", + added: f.added_lines, + removed: f.removed_lines + } + end + + Gitlab::Json.dump(diffs_map) + end + + # Disabled undercoverage reports for this method + # as it returns a false positive on the last line, + # which is covered in the tests + # + # Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/357381 + # + # :nocov: + def diff_file_path_text(diff_file, max: 60) + path = diff_file.new_path + + return path unless path.size > max && max > 3 + + "...#{path[-(max - 3)..]}" + end + # :nocov: + + private + + def diff_file_changed_icon(diff_file) + if diff_file.deleted_file? + "file-deletion" + elsif diff_file.new_file? + "file-addition" + else + "file-modified" + end + end + + def diff_file_changed_icon_color(diff_file) + if diff_file.deleted_file? + "danger" + elsif diff_file.new_file? + "success" + end + end + end +end diff --git a/app/components/pajamas/alert_component.html.haml b/app/components/pajamas/alert_component.html.haml new file mode 100644 index 00000000000..a1d3c700e57 --- /dev/null +++ b/app/components/pajamas/alert_component.html.haml @@ -0,0 +1,13 @@ +.gl-alert{ role: 'alert', class: ["gl-alert-#{@variant}", @alert_class], data: @alert_data } + = sprite_icon(icon, css_class: icon_classes) + - if @dismissible + %button.btn.gl-dismiss-btn.btn-default.btn-sm.gl-button.btn-default-tertiary.btn-icon.js-close{ type: 'button', + aria: { label: _('Dismiss') }, + class: @close_button_class, + data: @close_button_data } + = sprite_icon('close') + .gl-alert-content{ role: 'alert' } + - if @title + %h4.gl-alert-title + = @title + = content diff --git a/app/components/pajamas/alert_component.rb b/app/components/pajamas/alert_component.rb new file mode 100644 index 00000000000..4bb6c41661b --- /dev/null +++ b/app/components/pajamas/alert_component.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +# Renders a GlAlert root element +module Pajamas + class AlertComponent < Pajamas::Component + # @param [String] title + # @param [Symbol] variant + # @param [Boolean] dismissible + # @param [String] alert_class + # @param [Hash] alert_data + # @param [String] close_button_class + # @param [Hash] close_button_data + def initialize( + title: nil, variant: :info, dismissible: true, + alert_class: nil, alert_data: {}, close_button_class: nil, close_button_data: {}) + @title = title + @variant = variant + @dismissible = dismissible + @alert_class = alert_class + @alert_data = alert_data + @close_button_class = close_button_class + @close_button_data = close_button_data + end + + private + + delegate :sprite_icon, to: :helpers + + ICONS = { + info: 'information-o', + warning: 'warning', + success: 'check-circle', + danger: 'error', + tip: 'bulb' + }.freeze + + def icon + ICONS[@variant] + end + + def icon_classes + "gl-alert-icon#{' gl-alert-icon-no-title' if @title.nil?}" + end + end +end |