summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/milestone_select.js3
-rw-r--r--app/assets/stylesheets/framework/gitlab-theme.scss20
-rw-r--r--app/assets/stylesheets/new_sidebar.scss14
-rw-r--r--app/assets/stylesheets/pages/issuable.scss6
-rw-r--r--app/controllers/boards/issues_controller.rb13
-rw-r--r--app/models/label.rb7
-rw-r--r--app/models/project_services/pipelines_email_service.rb2
-rw-r--r--app/models/repository.rb6
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml4
-rw-r--r--changelogs/unreleased/34510-board-issues-sql-speedup.yml5
-rw-r--r--changelogs/unreleased/35978-milestone-title.yml5
-rw-r--r--changelogs/unreleased/37576-renamed-files-have-escaped-html-for-the-inline-diff-in-the-header.yml5
-rw-r--r--changelogs/unreleased/37759-also-treat-newlines-as-separator.yml5
-rw-r--r--lib/gitlab/diff/inline_diff_marker.rb3
-rw-r--r--spec/controllers/boards/issues_controller_spec.rb11
-rw-r--r--spec/features/projects/diffs/diff_show_spec.rb13
-rw-r--r--spec/helpers/diff_helper_spec.rb4
-rw-r--r--spec/models/project_services/pipelines_email_service_spec.rb37
-rw-r--r--spec/workers/git_garbage_collect_worker_spec.rb4
19 files changed, 124 insertions, 43 deletions
diff --git a/app/assets/javascripts/milestone_select.js b/app/assets/javascripts/milestone_select.js
index 04579058688..4675b1fcb8f 100644
--- a/app/assets/javascripts/milestone_select.js
+++ b/app/assets/javascripts/milestone_select.js
@@ -45,7 +45,7 @@ import _ from 'underscore';
if (issueUpdateURL) {
milestoneLinkTemplate = _.template('<a href="/<%- full_path %>/milestones/<%- iid %>" class="bold has-tooltip" data-container="body" title="<%- remaining %>"><%- title %></a>');
milestoneLinkNoneTemplate = '<span class="no-value">None</span>';
- collapsedSidebarLabelTemplate = _.template('<span class="has-tooltip" data-container="body" title="<%- remaining %>" data-placement="left"> <%- title %> </span>');
+ collapsedSidebarLabelTemplate = _.template('<span class="has-tooltip" data-container="body" title="<%- name %><br /><%- remaining %>" data-placement="left" data-html="true"> <%- title %> </span>');
}
return $dropdown.glDropdown({
showMenuAbove: showMenuAbove,
@@ -208,6 +208,7 @@ import _ from 'underscore';
if (data.milestone != null) {
data.milestone.full_path = _this.currentProject.full_path;
data.milestone.remaining = gl.utils.timeFor(data.milestone.due_date);
+ data.milestone.name = data.milestone.title;
$value.html(milestoneLinkTemplate(data.milestone));
return $sidebarCollapsedValue.find('span').html(collapsedSidebarLabelTemplate(data.milestone));
} else {
diff --git a/app/assets/stylesheets/framework/gitlab-theme.scss b/app/assets/stylesheets/framework/gitlab-theme.scss
index 71f764923ff..f844d6f1d5a 100644
--- a/app/assets/stylesheets/framework/gitlab-theme.scss
+++ b/app/assets/stylesheets/framework/gitlab-theme.scss
@@ -158,11 +158,23 @@
box-shadow: inset 4px 0 0 $color-700;
> a {
- color: $color-900;
+ color: $color-800;
}
svg {
- fill: $color-900;
+ fill: $color-800;
+ }
+ }
+
+ .sidebar-top-level-items > li.active .badge {
+ color: $color-800;
+ }
+
+ .nav-links li.active a {
+ border-bottom-color: $color-500;
+
+ .badge {
+ font-weight: $gl-font-weight-bold;
}
}
}
@@ -261,5 +273,9 @@ body {
fill: $theme-gray-900;
}
}
+
+ .sidebar-top-level-items > li.active .badge {
+ color: $theme-gray-900;
+ }
}
}
diff --git a/app/assets/stylesheets/new_sidebar.scss b/app/assets/stylesheets/new_sidebar.scss
index e4c12e46056..952002c83d1 100644
--- a/app/assets/stylesheets/new_sidebar.scss
+++ b/app/assets/stylesheets/new_sidebar.scss
@@ -3,8 +3,6 @@
@import "bootstrap/variables";
$active-background: rgba(0, 0, 0, .04);
-$active-border: $indigo-500;
-$active-color: $indigo-700;
$active-hover-background: $active-background;
$active-hover-color: $gl-text-color;
$inactive-badge-background: rgba(0, 0, 0, .08);
@@ -217,7 +215,6 @@ $new-sidebar-collapsed-width: 50px;
&:hover,
&:focus {
background: $active-background;
- color: $active-color;
}
}
}
@@ -317,7 +314,6 @@ $new-sidebar-collapsed-width: 50px;
}
.badge {
- color: $active-color;
font-weight: $gl-font-weight-bold;
}
@@ -494,13 +490,3 @@ $new-sidebar-collapsed-width: 50px;
.with-performance-bar .boards-list {
height: calc(100vh - #{$new-navbar-height} - #{$performance-bar-height});
}
-
-
-// Change color of all horizontal tabs to match the new indigo color
-.nav-links li.active a {
- border-bottom-color: $active-border;
-
- .badge {
- font-weight: $gl-font-weight-bold;
- }
-}
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index d8a15faf7e9..d01ee4b033c 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -449,6 +449,12 @@
}
}
}
+
+ .milestone-title span {
+ @include str-truncated(100%);
+ display: block;
+ margin: 0 4px;
+ }
}
a {
diff --git a/app/controllers/boards/issues_controller.rb b/app/controllers/boards/issues_controller.rb
index 8d4ec2d6d9d..0d74078645a 100644
--- a/app/controllers/boards/issues_controller.rb
+++ b/app/controllers/boards/issues_controller.rb
@@ -11,9 +11,15 @@ module Boards
issues = Boards::Issues::ListService.new(board_parent, current_user, filter_params).execute
issues = issues.page(params[:page]).per(params[:per] || 20)
make_sure_position_is_set(issues)
+ issues = issues.preload(:project,
+ :milestone,
+ :assignees,
+ labels: [:priorities],
+ notes: [:award_emoji, :author]
+ )
render json: {
- issues: serialize_as_json(issues.preload(:project)),
+ issues: serialize_as_json(issues),
size: issues.total_count
}
end
@@ -76,14 +82,13 @@ module Boards
def serialize_as_json(resource)
resource.as_json(
- labels: true,
only: [:id, :iid, :project_id, :title, :confidential, :due_date, :relative_position],
+ labels: true,
include: {
project: { only: [:id, :path] },
assignees: { only: [:id, :name, :username], methods: [:avatar_url] },
milestone: { only: [:id, :title] }
- },
- user: current_user
+ }
)
end
end
diff --git a/app/models/label.rb b/app/models/label.rb
index 958141a7358..899028a01a0 100644
--- a/app/models/label.rb
+++ b/app/models/label.rb
@@ -127,7 +127,12 @@ class Label < ActiveRecord::Base
end
def priority(project)
- priorities.find_by(project: project).try(:priority)
+ priority = if priorities.loaded?
+ priorities.first { |p| p.project == project }
+ else
+ priorities.find_by(project: project)
+ end
+ priority.try(:priority)
end
def template?
diff --git a/app/models/project_services/pipelines_email_service.rb b/app/models/project_services/pipelines_email_service.rb
index 9d37184be2c..6a3118a11b8 100644
--- a/app/models/project_services/pipelines_email_service.rb
+++ b/app/models/project_services/pipelines_email_service.rb
@@ -80,6 +80,6 @@ class PipelinesEmailService < Service
end
def retrieve_recipients(data)
- recipients.to_s.split(',').reject(&:blank?)
+ recipients.to_s.split(/[,(?:\r?\n) ]+/).reject(&:empty?)
end
end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 035f85a0b46..6ed33e0c268 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -90,6 +90,12 @@ class Repository
)
end
+ # we need to have this method here because it is not cached in ::Git and
+ # the method is called multiple times for every request
+ def has_visible_content?
+ branch_count > 0
+ end
+
def inspect
"#<#{self.class.name}:#{@disk_path}>"
end
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index 0afa48b392c..9cae3f51825 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -24,9 +24,9 @@
.block.milestone
.sidebar-collapsed-icon
= icon('clock-o', 'aria-hidden': 'true')
- %span
+ %span.milestone-title
- if issuable.milestone
- %span.has-tooltip{ title: milestone_remaining_days(issuable.milestone), data: { container: 'body', html: 1, placement: 'left' } }
+ %span.has-tooltip{ title: "#{issuable.milestone.title}<br>#{milestone_remaining_days(issuable.milestone)}", data: { container: 'body', html: 1, placement: 'left' } }
= issuable.milestone.title
- else
None
diff --git a/changelogs/unreleased/34510-board-issues-sql-speedup.yml b/changelogs/unreleased/34510-board-issues-sql-speedup.yml
new file mode 100644
index 00000000000..244ff7e9dfa
--- /dev/null
+++ b/changelogs/unreleased/34510-board-issues-sql-speedup.yml
@@ -0,0 +1,5 @@
+---
+title: Optimize the boards' issues fetching.
+merge_request: 14198
+author:
+type: other
diff --git a/changelogs/unreleased/35978-milestone-title.yml b/changelogs/unreleased/35978-milestone-title.yml
new file mode 100644
index 00000000000..1a4b71328c1
--- /dev/null
+++ b/changelogs/unreleased/35978-milestone-title.yml
@@ -0,0 +1,5 @@
+---
+title: Truncate milestone title if sidebar is collapsed
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/37576-renamed-files-have-escaped-html-for-the-inline-diff-in-the-header.yml b/changelogs/unreleased/37576-renamed-files-have-escaped-html-for-the-inline-diff-in-the-header.yml
new file mode 100644
index 00000000000..8c328eb0950
--- /dev/null
+++ b/changelogs/unreleased/37576-renamed-files-have-escaped-html-for-the-inline-diff-in-the-header.yml
@@ -0,0 +1,5 @@
+---
+title: Fix the diff file header from being html escaped for renamed files.
+merge_request: 14121
+author:
+type: fixed
diff --git a/changelogs/unreleased/37759-also-treat-newlines-as-separator.yml b/changelogs/unreleased/37759-also-treat-newlines-as-separator.yml
new file mode 100644
index 00000000000..6894e650c11
--- /dev/null
+++ b/changelogs/unreleased/37759-also-treat-newlines-as-separator.yml
@@ -0,0 +1,5 @@
+---
+title: Allow using newlines in pipeline email service recipients
+merge_request: 14250
+author:
+type: fixed
diff --git a/lib/gitlab/diff/inline_diff_marker.rb b/lib/gitlab/diff/inline_diff_marker.rb
index 919965100ae..010b4be7b40 100644
--- a/lib/gitlab/diff/inline_diff_marker.rb
+++ b/lib/gitlab/diff/inline_diff_marker.rb
@@ -2,9 +2,10 @@ module Gitlab
module Diff
class InlineDiffMarker < Gitlab::StringRangeMarker
def mark(line_inline_diffs, mode: nil)
- super(line_inline_diffs) do |text, left:, right:|
+ mark = super(line_inline_diffs) do |text, left:, right:|
%{<span class="#{html_class_names(left, right, mode)}">#{text}</span>}
end
+ mark.html_safe
end
private
diff --git a/spec/controllers/boards/issues_controller_spec.rb b/spec/controllers/boards/issues_controller_spec.rb
index dfa06c78d46..5163099cd98 100644
--- a/spec/controllers/boards/issues_controller_spec.rb
+++ b/spec/controllers/boards/issues_controller_spec.rb
@@ -45,6 +45,17 @@ describe Boards::IssuesController do
expect(parsed_response.length).to eq 2
expect(development.issues.map(&:relative_position)).not_to include(nil)
end
+
+ it 'avoids N+1 database queries' do
+ create(:labeled_issue, project: project, labels: [development])
+ control_count = ActiveRecord::QueryRecorder.new { list_issues(user: user, board: board, list: list2) }.count
+
+ # 25 issues is bigger than the page size
+ # the relative position will ignore the `#make_sure_position_set` queries
+ create_list(:labeled_issue, 25, project: project, labels: [development], assignees: [johndoe], relative_position: 1)
+
+ expect { list_issues(user: user, board: board, list: list2) }.not_to exceed_query_limit(control_count)
+ end
end
context 'with invalid list id' do
diff --git a/spec/features/projects/diffs/diff_show_spec.rb b/spec/features/projects/diffs/diff_show_spec.rb
index bc102895aaf..a6f52c9ef58 100644
--- a/spec/features/projects/diffs/diff_show_spec.rb
+++ b/spec/features/projects/diffs/diff_show_spec.rb
@@ -108,6 +108,19 @@ feature 'Diff file viewer', :js do
end
end
+ context 'renamed file' do
+ before do
+ visit_commit('6907208d755b60ebeacb2e9dfea74c92c3449a1f')
+ end
+
+ it 'shows the filename with diff highlight' do
+ within('.file-header-content') do
+ expect(page).to have_css('.idiff.left.right.deletion')
+ expect(page).to have_content('files/js/commit.coffee')
+ end
+ end
+ end
+
context 'binary file that appears to be text in the first 1024 bytes' do
before do
# The file we're visiting is smaller than 10 KB and we want it collapsed
diff --git a/spec/helpers/diff_helper_spec.rb b/spec/helpers/diff_helper_spec.rb
index 0deea0ff6a3..f9c31ac61d8 100644
--- a/spec/helpers/diff_helper_spec.rb
+++ b/spec/helpers/diff_helper_spec.rb
@@ -136,9 +136,9 @@ describe DiffHelper do
marked_old_line, marked_new_line = mark_inline_diffs(old_line, new_line)
expect(marked_old_line).to eq(%q{abc <span class="idiff left right deletion">'def'</span>})
- expect(marked_old_line).not_to be_html_safe
+ expect(marked_old_line).to be_html_safe
expect(marked_new_line).to eq(%q{abc <span class="idiff left right addition">"def"</span>})
- expect(marked_new_line).not_to be_html_safe
+ expect(marked_new_line).to be_html_safe
end
end
diff --git a/spec/models/project_services/pipelines_email_service_spec.rb b/spec/models/project_services/pipelines_email_service_spec.rb
index 5faab9ba38b..be07ca2d945 100644
--- a/spec/models/project_services/pipelines_email_service_spec.rb
+++ b/spec/models/project_services/pipelines_email_service_spec.rb
@@ -6,7 +6,8 @@ describe PipelinesEmailService, :mailer do
end
let(:project) { create(:project, :repository) }
- let(:recipient) { 'test@gitlab.com' }
+ let(:recipients) { 'test@gitlab.com' }
+ let(:receivers) { [recipients] }
let(:data) do
Gitlab::DataBuilder::Pipeline.build(pipeline)
@@ -48,18 +49,24 @@ describe PipelinesEmailService, :mailer do
shared_examples 'sending email' do
before do
+ subject.recipients = recipients
+
perform_enqueued_jobs do
run
end
end
it 'sends email' do
- should_only_email(double(notification_email: recipient), kind: :bcc)
+ emails = receivers.map { |r| double(notification_email: r) }
+
+ should_only_email(*emails, kind: :bcc)
end
end
shared_examples 'not sending email' do
before do
+ subject.recipients = recipients
+
perform_enqueued_jobs do
run
end
@@ -75,10 +82,6 @@ describe PipelinesEmailService, :mailer do
subject.test(data)
end
- before do
- subject.recipients = recipient
- end
-
context 'when pipeline is failed' do
before do
data[:object_attributes][:status] = 'failed'
@@ -104,10 +107,6 @@ describe PipelinesEmailService, :mailer do
end
context 'with recipients' do
- before do
- subject.recipients = recipient
- end
-
context 'with failed pipeline' do
before do
data[:object_attributes][:status] = 'failed'
@@ -152,9 +151,7 @@ describe PipelinesEmailService, :mailer do
end
context 'with empty recipients list' do
- before do
- subject.recipients = ' ,, '
- end
+ let(:recipients) { ' ,, ' }
context 'with failed pipeline' do
before do
@@ -165,5 +162,19 @@ describe PipelinesEmailService, :mailer do
it_behaves_like 'not sending email'
end
end
+
+ context 'with recipients list separating with newlines' do
+ let(:recipients) { "\ntest@gitlab.com, \r\nexample@gitlab.com" }
+ let(:receivers) { %w[test@gitlab.com example@gitlab.com] }
+
+ context 'with failed pipeline' do
+ before do
+ data[:object_attributes][:status] = 'failed'
+ pipeline.update(status: 'failed')
+ end
+
+ it_behaves_like 'sending email'
+ end
+ end
end
end
diff --git a/spec/workers/git_garbage_collect_worker_spec.rb b/spec/workers/git_garbage_collect_worker_spec.rb
index 6f9ddb6c63c..f7b67b8efc6 100644
--- a/spec/workers/git_garbage_collect_worker_spec.rb
+++ b/spec/workers/git_garbage_collect_worker_spec.rb
@@ -31,8 +31,8 @@ describe GitGarbageCollectWorker do
expect_any_instance_of(Repository).to receive(:after_create_branch).and_call_original
expect_any_instance_of(Repository).to receive(:branch_names).and_call_original
+ expect_any_instance_of(Repository).to receive(:has_visible_content?).and_call_original
expect_any_instance_of(Gitlab::Git::Repository).to receive(:branch_count).and_call_original
- expect_any_instance_of(Gitlab::Git::Repository).to receive(:has_visible_content?).and_call_original
subject.perform(project.id, :gc, lease_key, lease_uuid)
end
@@ -77,8 +77,8 @@ describe GitGarbageCollectWorker do
expect_any_instance_of(Repository).to receive(:after_create_branch).and_call_original
expect_any_instance_of(Repository).to receive(:branch_names).and_call_original
+ expect_any_instance_of(Repository).to receive(:has_visible_content?).and_call_original
expect_any_instance_of(Gitlab::Git::Repository).to receive(:branch_count).and_call_original
- expect_any_instance_of(Gitlab::Git::Repository).to receive(:has_visible_content?).and_call_original
subject.perform(project.id)
end