Commit b1e93200 authored by Robert May's avatar Robert May Committed by Sean McGivern

Migrate diff stats view to component

Creates a new component class and migrates the stats
view to it.

Changelog: changed
parent cb4f76e0
# 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
.js-diff-stats-dropdown{ data: { changed: @changed, added: @added, deleted: @removed, files: diff_files_data } }
# 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
......@@ -195,24 +195,6 @@ module DiffHelper
!diff_file.deleted_file? && @merge_request && @merge_request.source_project
end
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
def render_overflow_warning?(diffs_collection)
diffs_collection.overflow?.tap do |overflown|
log_overflow_limits(diff_files: diffs_collection.raw_diff_files, collection_overflow: overflown)
......@@ -272,23 +254,6 @@ module DiffHelper
toggle_whitespace_link(url, options)
end
def diff_files_data(diff_files)
diffs_map = diff_files.map do |f|
{
href: "##{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
diffs_map.to_json
end
def hide_whitespace?
params[:w] == '1'
end
......@@ -302,14 +267,6 @@ module DiffHelper
link_to "#{hide_whitespace? ? 'Show' : 'Hide'} whitespace changes", url, class: options[:class]
end
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
def code_navigation_path(diffs)
Gitlab::CodeNavigationPath.new(merge_request.project, merge_request.diff_head_sha)
end
......
......@@ -24,7 +24,7 @@
.btn-group.gl-ml-3
= inline_diff_btn
= parallel_diff_btn
= render 'projects/diffs/stats', diff_files: diff_files
= render Diffs::StatsComponent.new(diff_files: diff_files)
- if render_overflow_warning?(diffs)
= render 'projects/diffs/warning', diff_files: diffs
......
.js-diff-stats-dropdown{ data: { changed: diff_files.size, added: diff_files.sum(&:added_lines), deleted: diff_files.sum(&:removed_lines), files: diff_files_data(diff_files) } }
# frozen_string_literal: true
require "spec_helper"
RSpec.describe Diffs::StatsComponent, type: :component do
include RepoHelpers
subject(:component) do
described_class.new(diff_files: diff_files)
end
let_it_be(:project) { create(:project, :repository) }
let_it_be(:repository) { project.repository }
let_it_be(:commit) { project.commit(sample_commit.id) }
let_it_be(:diffs) { commit.raw_diffs }
let_it_be(:diff) { diffs.first }
let_it_be(:diff_refs) { commit.diff_refs }
let_it_be(:diff_file) { Gitlab::Diff::File.new(diff, diff_refs: diff_refs, repository: repository) }
let_it_be(:diff_files) { [diff_file] }
describe "rendered component" do
subject { rendered_component }
let(:element) { page.find(".js-diff-stats-dropdown") }
before do
render_inline component
end
it { is_expected.to have_selector(".js-diff-stats-dropdown") }
it "renders the data attributes" do
expect(element["data-changed"]).to eq("1")
expect(element["data-added"]).to eq("10")
expect(element["data-deleted"]).to eq("3")
expect(Gitlab::Json.parse(element["data-files"])).to eq([{
"href" => "##{Digest::SHA1.hexdigest(diff_file.file_path)}",
"title" => diff_file.new_path,
"name" => diff_file.file_path,
"path" => diff_file.file_path,
"icon" => "file-modified",
"iconColor" => "",
"added" => diff_file.added_lines,
"removed" => diff_file.removed_lines
}])
end
end
describe "#diff_file_path_text" do
it "returns full path by default" do
expect(subject.diff_file_path_text(diff_file)).to eq(diff_file.new_path)
end
it "returns truncated path" do
expect(subject.diff_file_path_text(diff_file, max: 10)).to eq("...open.rb")
end
it "returns the path if max is oddly small" do
expect(subject.diff_file_path_text(diff_file, max: 3)).to eq(diff_file.new_path)
end
it "returns the path if max is oddly large" do
expect(subject.diff_file_path_text(diff_file, max: 100)).to eq(diff_file.new_path)
end
end
end
......@@ -425,16 +425,6 @@ RSpec.describe DiffHelper do
end
end
describe '#diff_file_path_text' do
it 'returns full path by default' do
expect(diff_file_path_text(diff_file)).to eq(diff_file.new_path)
end
it 'returns truncated path' do
expect(diff_file_path_text(diff_file, max: 10)).to eq("...open.rb")
end
end
describe "#collapsed_diff_url" do
let(:params) do
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment