Merge branch '23634-remove-project-grouping' into 'master'

Don't group issue, merge request and TODO lists by project

Closes #23634

See merge request !8519
This commit is contained in:
Sean McGivern 2017-01-30 10:25:36 +00:00
commit 7bd3ee3bfb
27 changed files with 235 additions and 96 deletions

View File

@ -85,7 +85,7 @@
},
success: (data) => {
$target.remove();
$('.prepend-top-default').html('<div class="nothing-here-block">You\'re all done!</div>');
$('.js-todos-all').html('<div class="nothing-here-block">You\'re all done!</div>');
return this.updateBadges(data);
}
});

View File

@ -162,6 +162,10 @@
}
}
}
&.panel-without-border {
border: 0;
}
}
.panel-succes .panel-heading,

View File

@ -76,6 +76,10 @@
font-size: 14px;
}
.action-name {
font-weight: normal;
}
.todo-body {
.todo-note {
word-wrap: break-word;

View File

@ -4,6 +4,7 @@ class DashboardController < Dashboard::ApplicationController
before_action :event_filter, only: :activity
before_action :projects, only: [:issues, :merge_requests]
before_action :set_show_full_reference, only: [:issues, :merge_requests]
respond_to :html
@ -34,4 +35,8 @@ class DashboardController < Dashboard::ApplicationController
@events = @event_filter.apply_filter(@events).with_associations
@events = @events.limit(20).offset(params[:offset] || 0)
end
def set_show_full_reference
@show_full_reference = true
end
end

View File

@ -162,6 +162,10 @@ module IssuablesHelper
]
end
def issuable_reference(issuable)
@show_full_reference ? issuable.to_reference(full: true) : issuable.to_reference(@group || @project)
end
def issuable_filter_present?
issuable_filter_params.any? { |k| params.key?(k) }
end

View File

@ -100,8 +100,8 @@ class Commit
commit_reference(from_project, id, full: full)
end
def reference_link_text(from_project = nil)
commit_reference(from_project, short_id)
def reference_link_text(from_project = nil, full: false)
commit_reference(from_project, short_id, full: full)
end
def diff_line_count

View File

@ -97,10 +97,11 @@ class Issue < ActiveRecord::Base
end
end
def to_reference(from_project = nil, full: false)
# `from` argument can be a Namespace or Project.
def to_reference(from = nil, full: false)
reference = "#{self.class.reference_prefix}#{iid}"
"#{project.to_reference(from_project, full: full)}#{reference}"
"#{project.to_reference(from, full: full)}#{reference}"
end
def referenced_merge_requests(current_user = nil)

View File

@ -179,10 +179,11 @@ class MergeRequest < ActiveRecord::Base
work_in_progress?(title) ? title : "WIP: #{title}"
end
def to_reference(from_project = nil, full: false)
# `from` argument can be a Namespace or Project.
def to_reference(from = nil, full: false)
reference = "#{self.class.reference_prefix}#{iid}"
"#{project.to_reference(from_project, full: full)}#{reference}"
"#{project.to_reference(from, full: full)}#{reference}"
end
def first_commit

View File

@ -591,10 +591,11 @@ class Project < ActiveRecord::Base
end
end
def to_reference(from_project = nil, full: false)
if full || cross_namespace_reference?(from_project)
# `from` argument can be a Namespace or Project.
def to_reference(from = nil, full: false)
if full || cross_namespace_reference?(from)
path_with_namespace
elsif cross_project_reference?(from_project)
elsif cross_project_reference?(from)
path
end
end
@ -1291,21 +1292,26 @@ class Project < ActiveRecord::Base
private
def cross_namespace_reference?(from)
case from
when Project
namespace != from.namespace
when Namespace
namespace != from
end
end
# Check if a reference is being done cross-project
#
# from_project - Refering Project object
def cross_project_reference?(from_project)
from_project && self != from_project
def cross_project_reference?(from)
return true if from.is_a?(Namespace)
from && self != from
end
def pushes_since_gc_redis_key
"projects/#{id}/pushes_since_gc"
end
def cross_namespace_reference?(from_project)
from_project && namespace != from_project.namespace
end
def default_branch_protected?
current_application_settings.default_branch_protection == Gitlab::Access::PROTECTION_FULL ||
current_application_settings.default_branch_protection == Gitlab::Access::PROTECTION_DEV_CAN_MERGE

View File

@ -103,9 +103,9 @@ class Todo < ActiveRecord::Base
def target_reference
if for_commit?
target.short_id
target.reference_link_text(full: true)
else
target.to_reference
target.to_reference(full: true)
end
end

View File

@ -15,6 +15,4 @@
= render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue"
= render 'shared/issuable/filter', type: :issues
.prepend-top-default
= render 'shared/issues'
= render 'shared/issues'

View File

@ -7,6 +7,4 @@
= render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New Merge Request"
= render 'shared/issuable/filter', type: :merge_requests
.prepend-top-default
= render 'shared/merge_requests'
= render 'shared/merge_requests'

View File

@ -11,8 +11,11 @@
= link_to_author(todo)
- else
(removed)
%span.todo-label
%span.action-name
= todo_action_name(todo)
%span.todo-label
- if todo.target
= todo_target_link(todo)
- else

View File

@ -67,18 +67,14 @@
= sort_title_oldest_created
.prepend-top-default
.js-todos-all
- if @todos.any?
.js-todos-options{ data: {per_page: @todos.limit_value, current_page: @todos.current_page, total_pages: @todos.total_pages} }
- @todos.group_by(&:project).each do |group|
.panel.panel-default.panel-small
- project = group[0]
.panel-heading
= link_to project.name_with_namespace, namespace_project_path(project.namespace, project)
.panel.panel-default.panel-small.panel-without-border
%ul.content-list.todos-list
= render group[1]
= render @todos
= paginate @todos, theme: "gitlab"
- elsif current_user.todos.any?
.todos-all-done
= render "shared/empty_states/todos_all_done.svg"

View File

@ -23,7 +23,6 @@
- if current_user
To see all issues you should visit #{link_to 'dashboard', issues_dashboard_path} page.
.prepend-top-default
= render 'shared/issues'
= render 'shared/issues'
- else
= render 'shared/empty_states/issues', project_select_button: true

View File

@ -15,5 +15,4 @@
- if current_user
To see all merge requests you should visit #{link_to 'dashboard', merge_requests_dashboard_path} page.
.prepend-top-default
= render 'shared/merge_requests'
= render 'shared/merge_requests'

View File

@ -34,7 +34,7 @@
= note_count
.issue-info
#{issue.to_reference} &middot;
#{issuable_reference(issue)} &middot;
opened #{time_ago_with_tooltip(issue.created_at, placement: 'bottom')}
by #{link_to_member(@project, issue.author, avatar: false)}
- if issue.milestone

View File

@ -46,7 +46,7 @@
= note_count
.merge-request-info
#{merge_request.to_reference} &middot;
#{issuable_reference(merge_request)} &middot;
opened #{time_ago_with_tooltip(merge_request.created_at, placement: 'bottom')}
by #{link_to_member(@project, merge_request.author, avatar: false)}
- if merge_request.target_project.default_branch != merge_request.target_branch

View File

@ -1,16 +1,7 @@
- if @issues.to_a.any?
- @issues.group_by(&:project).each do |group|
.panel.panel-default.panel-small
- project = group[0]
.panel-heading
= link_to project.name_with_namespace, namespace_project_issues_path(project.namespace, project)
- if can?(current_user, :create_issue, project)
.pull-right
= link_to 'New issue', new_namespace_project_issue_path(project.namespace, project)
%ul.content-list.issues-list
- group[1].each do |issue|
= render 'projects/issues/issue', issue: issue
.panel.panel-default.panel-small.panel-without-border
%ul.content-list.issues-list
= render partial: 'projects/issues/issue', collection: @issues
= paginate @issues, theme: "gitlab"
- else
= render 'shared/empty_states/issues'

View File

@ -1,16 +1,8 @@
- if @merge_requests.to_a.any?
- @merge_requests.group_by(&:target_project).each do |group|
.panel.panel-default.panel-small
- project = group[0]
.panel-heading
= link_to project.name_with_namespace, namespace_project_merge_requests_path(project.namespace, project)
- if can?(current_user, :create_merge_request, project)
.pull-right
= link_to 'New merge request', new_namespace_project_merge_request_path(project.namespace, project)
.panel.panel-default.panel-small.panel-without-border
%ul.content-list.mr-list
= render partial: 'projects/merge_requests/merge_request', collection: @merge_requests
%ul.content-list.mr-list
- group[1].each do |merge_request|
= render 'projects/merge_requests/merge_request', merge_request: merge_request
= paginate @merge_requests, theme: "gitlab"
- else

View File

@ -0,0 +1,4 @@
---
title: Don't group issues by project on group-level and dashboard issue indexes.
merge_request: 8111
author: Bernardo Castro

View File

@ -25,15 +25,18 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps
end
step 'I should see todos assigned to me' do
merge_request_reference = merge_request.to_reference(full: true)
issue_reference = issue.to_reference(full: true)
page.within('.todos-pending-count') { expect(page).to have_content '4' }
expect(page).to have_content 'To do 4'
expect(page).to have_content 'Done 0'
expect(page).to have_link project.name_with_namespace
should_see_todo(1, "John Doe assigned you merge request #{merge_request.to_reference}", merge_request.title)
should_see_todo(2, "John Doe mentioned you on issue #{issue.to_reference}", "#{current_user.to_reference} Wdyt?")
should_see_todo(3, "John Doe assigned you issue #{issue.to_reference}", issue.title)
should_see_todo(4, "Mary Jane mentioned you on issue #{issue.to_reference}", issue.title)
should_see_todo(1, "John Doe assigned you merge request #{merge_request_reference}", merge_request.title)
should_see_todo(2, "John Doe mentioned you on issue #{issue_reference}", "#{current_user.to_reference} Wdyt?")
should_see_todo(3, "John Doe assigned you issue #{issue_reference}", issue.title)
should_see_todo(4, "Mary Jane mentioned you on issue #{issue_reference}", issue.title)
end
step 'I mark the todo as done' do
@ -44,10 +47,13 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps
page.within('.todos-pending-count') { expect(page).to have_content '3' }
expect(page).to have_content 'To do 3'
expect(page).to have_content 'Done 1'
should_not_see_todo "John Doe assigned you merge request #{merge_request.to_reference}"
should_not_see_todo "John Doe assigned you merge request #{merge_request.to_reference(full: true)}"
end
step 'I mark all todos as done' do
merge_request_reference = merge_request.to_reference(full: true)
issue_reference = issue.to_reference(full: true)
click_link 'Mark all as done'
page.within('.todos-pending-count') { expect(page).to have_content '0' }
@ -55,27 +61,30 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps
expect(page).to have_content 'Done 4'
expect(page).to have_content "You're all done!"
expect('.prepend-top-default').not_to have_link project.name_with_namespace
should_not_see_todo "John Doe assigned you merge request #{merge_request.to_reference}"
should_not_see_todo "John Doe mentioned you on issue #{issue.to_reference}"
should_not_see_todo "John Doe assigned you issue #{issue.to_reference}"
should_not_see_todo "Mary Jane mentioned you on issue #{issue.to_reference}"
should_not_see_todo "John Doe assigned you merge request #{merge_request_reference}"
should_not_see_todo "John Doe mentioned you on issue #{issue_reference}"
should_not_see_todo "John Doe assigned you issue #{issue_reference}"
should_not_see_todo "Mary Jane mentioned you on issue #{issue_reference}"
end
step 'I should see the todo marked as done' do
click_link 'Done 1'
expect(page).to have_link project.name_with_namespace
should_see_todo(1, "John Doe assigned you merge request #{merge_request.to_reference}", merge_request.title, false)
should_see_todo(1, "John Doe assigned you merge request #{merge_request.to_reference(full: true)}", merge_request.title, false)
end
step 'I should see all todos marked as done' do
merge_request_reference = merge_request.to_reference(full: true)
issue_reference = issue.to_reference(full: true)
click_link 'Done 4'
expect(page).to have_link project.name_with_namespace
should_see_todo(1, "John Doe assigned you merge request #{merge_request.to_reference}", merge_request.title, false)
should_see_todo(2, "John Doe mentioned you on issue #{issue.to_reference}", "#{current_user.to_reference} Wdyt?", false)
should_see_todo(3, "John Doe assigned you issue #{issue.to_reference}", issue.title, false)
should_see_todo(4, "Mary Jane mentioned you on issue #{issue.to_reference}", issue.title, false)
should_see_todo(1, "John Doe assigned you merge request #{merge_request_reference}", merge_request.title, false)
should_see_todo(2, "John Doe mentioned you on issue #{issue_reference}", "#{current_user.to_reference} Wdyt?", false)
should_see_todo(3, "John Doe assigned you issue #{issue_reference}", issue.title, false)
should_see_todo(4, "Mary Jane mentioned you on issue #{issue_reference}", issue.title, false)
end
step 'I filter by "Enterprise"' do
@ -111,16 +120,16 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps
end
step 'I should not see todos related to "Mary Jane" in the list' do
should_not_see_todo "Mary Jane mentioned you on issue #{issue.to_reference}"
should_not_see_todo "Mary Jane mentioned you on issue #{issue.to_reference(full: true)}"
end
step 'I should not see todos related to "Merge Requests" in the list' do
should_not_see_todo "John Doe assigned you merge request #{merge_request.to_reference}"
should_not_see_todo "John Doe assigned you merge request #{merge_request.to_reference(full: true)}"
end
step 'I should not see todos related to "Assignments" in the list' do
should_not_see_todo "John Doe assigned you merge request #{merge_request.to_reference}"
should_not_see_todo "John Doe assigned you issue #{issue.to_reference}"
should_not_see_todo "John Doe assigned you merge request #{merge_request.to_reference(full: true)}"
should_not_see_todo "John Doe assigned you issue #{issue.to_reference(full: true)}"
end
step 'I click on the todo' do

View File

@ -171,7 +171,7 @@ describe 'Dashboard Todos', feature: true do
it 'links to the pipelines for the merge request' do
href = pipelines_namespace_project_merge_request_path(project.namespace, project, todo.target)
expect(page).to have_link "merge request #{todo.target.to_reference}", href
expect(page).to have_link "merge request #{todo.target.to_reference(full: true)}", href
end
end
end

View File

@ -115,6 +115,46 @@ describe IssuablesHelper do
end
end
describe '#issuable_reference' do
context 'when show_full_reference truthy' do
it 'display issuable full reference' do
assign(:show_full_reference, true)
issue = build_stubbed(:issue)
expect(helper.issuable_reference(issue)).to eql(issue.to_reference(full: true))
end
end
context 'when show_full_reference falsey' do
context 'when @group present' do
it 'display issuable reference to @group' do
project = build_stubbed(:project)
assign(:show_full_reference, nil)
assign(:group, project.namespace)
issue = build_stubbed(:issue)
expect(helper.issuable_reference(issue)).to eql(issue.to_reference(project.namespace))
end
end
context 'when @project present' do
it 'display issuable reference to @project' do
project = build_stubbed(:project)
assign(:show_full_reference, nil)
assign(:group, nil)
assign(:project, project)
issue = build_stubbed(:issue)
expect(helper.issuable_reference(issue)).to eql(issue.to_reference(project))
end
end
end
end
describe '#issuable_filter_present?' do
it 'returns true when any key is present' do
allow(helper).to receive(:params).and_return(

View File

@ -23,21 +23,74 @@ describe Issue, models: true do
end
describe '#to_reference' do
let(:project) { build(:empty_project, name: 'sample-project') }
let(:issue) { build(:issue, iid: 1, project: project) }
let(:namespace) { build(:namespace, path: 'sample-namespace') }
let(:project) { build(:empty_project, name: 'sample-project', namespace: namespace) }
let(:issue) { build(:issue, iid: 1, project: project) }
let(:group) { create(:group, name: 'Group', path: 'sample-group') }
it 'returns a String reference to the object' do
expect(issue.to_reference).to eq "#1"
context 'when nil argument' do
it 'returns issue id' do
expect(issue.to_reference).to eq "#1"
end
end
it 'returns a String reference with the full path' do
expect(issue.to_reference(full: true)).to eq(project.path_with_namespace + '#1')
context 'when full is true' do
it 'returns complete path to the issue' do
expect(issue.to_reference(full: true)).to eq 'sample-namespace/sample-project#1'
expect(issue.to_reference(project, full: true)).to eq 'sample-namespace/sample-project#1'
expect(issue.to_reference(group, full: true)).to eq 'sample-namespace/sample-project#1'
end
end
context 'when same project argument' do
it 'returns issue id' do
expect(issue.to_reference(project)).to eq("#1")
end
end
context 'when cross namespace project argument' do
let(:another_namespace_project) { create(:empty_project, name: 'another-project') }
it 'returns complete path to the issue' do
expect(issue.to_reference(another_namespace_project)).to eq 'sample-namespace/sample-project#1'
end
end
it 'supports a cross-project reference' do
another_project = build(:empty_project, name: 'another-project', namespace: project.namespace)
expect(issue.to_reference(another_project)).to eq "sample-project#1"
end
context 'when same namespace / cross-project argument' do
let(:another_project) { create(:empty_project, namespace: namespace) }
it 'returns path to the issue with the project name' do
expect(issue.to_reference(another_project)).to eq 'sample-project#1'
end
end
context 'when different namespace / cross-project argument' do
let(:another_namespace) { create(:namespace, path: 'another-namespace') }
let(:another_project) { create(:empty_project, path: 'another-project', namespace: another_namespace) }
it 'returns full path to the issue' do
expect(issue.to_reference(another_project)).to eq 'sample-namespace/sample-project#1'
end
end
context 'when argument is a namespace' do
context 'with same project path' do
it 'returns path to the issue with the project name' do
expect(issue.to_reference(namespace)).to eq 'sample-project#1'
end
end
context 'with different project path' do
it 'returns full path to the issue' do
expect(issue.to_reference(group)).to eq 'sample-namespace/sample-project#1'
end
end
end
end
describe '#is_being_reassigned?' do

View File

@ -282,9 +282,10 @@ describe Project, models: true do
end
describe '#to_reference' do
let(:owner) { create(:user, name: 'Gitlab') }
let(:owner) { create(:user, name: 'Gitlab') }
let(:namespace) { create(:namespace, path: 'sample-namespace', owner: owner) }
let(:project) { create(:empty_project, path: 'sample-project', namespace: namespace) }
let(:project) { create(:empty_project, path: 'sample-project', namespace: namespace) }
let(:group) { create(:group, name: 'Group', path: 'sample-group', owner: owner) }
context 'when nil argument' do
it 'returns nil' do
@ -292,6 +293,14 @@ describe Project, models: true do
end
end
context 'when full is true' do
it 'returns complete path to the project' do
expect(project.to_reference(full: true)).to eq 'sample-namespace/sample-project'
expect(project.to_reference(project, full: true)).to eq 'sample-namespace/sample-project'
expect(project.to_reference(group, full: true)).to eq 'sample-namespace/sample-project'
end
end
context 'when same project argument' do
it 'returns nil' do
expect(project.to_reference(project)).to be_nil
@ -309,10 +318,33 @@ describe Project, models: true do
context 'when same namespace / cross-project argument' do
let(:another_project) { create(:empty_project, namespace: namespace) }
it 'returns complete path to the project' do
it 'returns path to the project' do
expect(project.to_reference(another_project)).to eq 'sample-project'
end
end
context 'when different namespace / cross-project argument' do
let(:another_namespace) { create(:namespace, path: 'another-namespace', owner: owner) }
let(:another_project) { create(:empty_project, path: 'another-project', namespace: another_namespace) }
it 'returns full path to the project' do
expect(project.to_reference(another_project)).to eq 'sample-namespace/sample-project'
end
end
context 'when argument is a namespace' do
context 'with same project path' do
it 'returns path to the project' do
expect(project.to_reference(namespace)).to eq 'sample-project'
end
end
context 'with different project path' do
it 'returns full path to the project' do
expect(project.to_reference(group)).to eq 'sample-namespace/sample-project'
end
end
end
end
describe '#to_human_reference' do

View File

@ -109,7 +109,7 @@ describe Todo, models: true do
end
describe '#target_reference' do
it 'returns the short commit id for commits' do
it 'returns commit full reference with short id' do
project = create(:project, :repository)
commit = project.commit
@ -117,12 +117,12 @@ describe Todo, models: true do
subject.target_type = 'Commit'
subject.commit_id = commit.id
expect(subject.target_reference).to eq commit.short_id
expect(subject.target_reference).to eq commit.reference_link_text(full: true)
end
it 'returns reference for issuables' do
it 'returns full reference for issuables' do
subject.target = issue
expect(subject.target_reference).to eq issue.to_reference
expect(subject.target_reference).to eq issue.to_reference(full: true)
end
end
end