Commit d8c42c0f authored by Fatih Acet's avatar Fatih Acet

Merge branch 'issue_7526' into 'master'

Add notes filters for epics

Closes #7581 and #7526

See merge request gitlab-org/gitlab-ee!8978
parents 3e0df212 ee229401
...@@ -12,3 +12,5 @@ class UserPreferenceEntity < Grape::Entity ...@@ -12,3 +12,5 @@ class UserPreferenceEntity < Grape::Entity
UserPreference::NOTES_FILTERS[:all_notes] UserPreference::NOTES_FILTERS[:all_notes]
end end
end end
UserPreferenceEntity.prepend(EE::UserPreferenceEntity)
...@@ -2972,6 +2972,7 @@ ActiveRecord::Schema.define(version: 20190115054216) do ...@@ -2972,6 +2972,7 @@ ActiveRecord::Schema.define(version: 20190115054216) do
t.datetime_with_timezone "updated_at", null: false t.datetime_with_timezone "updated_at", null: false
t.string "epics_sort" t.string "epics_sort"
t.integer "roadmap_epics_state" t.integer "roadmap_epics_state"
t.integer "epic_notes_filter", limit: 2, default: 0, null: false
t.index ["user_id"], name: "index_user_preferences_on_user_id", unique: true, using: :btree t.index ["user_id"], name: "index_user_preferences_on_user_id", unique: true, using: :btree
end end
......
...@@ -350,7 +350,7 @@ Replying to this email will, consequentially, create a new comment on the associ ...@@ -350,7 +350,7 @@ Replying to this email will, consequentially, create a new comment on the associ
For issues with many comments like activity notes and user comments, sometimes For issues with many comments like activity notes and user comments, sometimes
finding useful information can be hard. There is a way to filter comments from single notes and discussions for merge requests and issues. finding useful information can be hard. There is a way to filter comments from single notes and discussions for merge requests and issues.
From a merge request's **Discussion** tab, or from an issue overview, find the filter's dropdown menu on the right side of the page, from which you can choose one of the following options: From a merge request's **Discussion** tab, or from an epic/issue overview, find the filter's dropdown menu on the right side of the page, from which you can choose one of the following options:
- **Show all activity**: displays all user comments and system notes - **Show all activity**: displays all user comments and system notes
(issue updates, mentions from other issues, changes to the description, etc). (issue updates, mentions from other issues, changes to the description, etc).
......
...@@ -8,6 +8,8 @@ module EE ...@@ -8,6 +8,8 @@ module EE
validates :roadmap_epics_state, allow_nil: true, inclusion: { validates :roadmap_epics_state, allow_nil: true, inclusion: {
in: ::Epic.states.values, message: "%{value} is not a valid epic state" in: ::Epic.states.values, message: "%{value} is not a valid epic state"
} }
validates :epic_notes_filter, inclusion: { in: ::UserPreference::NOTES_FILTERS.values }, presence: true
end end
end end
end end
# frozen_string_literal: true
module EE
module UserPreferenceEntity
extend ActiveSupport::Concern
prepended do
expose :epic_notes_filter
end
end
end
...@@ -3,5 +3,5 @@ ...@@ -3,5 +3,5 @@
%section.js-vue-notes-event %section.js-vue-notes-event
#js-vue-notes{ data: { notes_data: notes_data(@epic).to_json, #js-vue-notes{ data: { notes_data: notes_data(@epic).to_json,
noteable_data: EpicSerializer.new(current_user: current_user).represent(@epic).to_json, noteable_data: EpicSerializer.new(current_user: current_user).represent(@epic).to_json,
current_user_data: UserSerializer.new.represent(current_user, only_path: true).to_json, noteable_type: 'epic', current_user_data: UserSerializer.new.represent(current_user, { only_path: true }, CurrentUserEntity).to_json, noteable_type: 'epic',
markdown_version: @issuable.cached_markdown_version } } markdown_version: @issuable.cached_markdown_version } }
...@@ -18,8 +18,10 @@ ...@@ -18,8 +18,10 @@
.content-block.emoji-block .content-block.emoji-block
.row .row
.col-sm-8.js-noteable-awards .col-sm-6.col-md-8.js-noteable-awards
= render 'award_emoji/awards_block', awardable: @epic, inline: true = render 'award_emoji/awards_block', awardable: @epic, inline: true
.col-sm-6.col-md-4.d-flex.justify-content-sm-end.align-items-md-top.mt-2.mt-sm-1
#js-vue-discussion-filter{ data: { default_filter: current_user&.notes_filter_for(@epic), notes_filters: UserPreference.notes_filters.to_json } }
%section.issuable-discussion %section.issuable-discussion
= render 'discussion' = render 'discussion'
---
title: Allow to filter notes in epics
merge_request: 8978
author:
type: added
class AddEpicNotesFilterToUserPreference < ActiveRecord::Migration[5.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
class UserPreference < ActiveRecord::Base
self.table_name = 'user_preferences'
NOTES_FILTERS = { all_notes: 0, comments: 1 }.freeze
end
disable_ddl_transaction!
def up
add_column_with_default :user_preferences,
:epic_notes_filter,
:integer,
default: UserPreference::NOTES_FILTERS[:all_notes],
allow_null: false,
limit: 2
end
def down
remove_column(:user_preferences, :epic_notes_filter)
end
end
...@@ -166,10 +166,13 @@ describe Groups::EpicsController do ...@@ -166,10 +166,13 @@ describe Groups::EpicsController do
before do before do
sign_in(user) sign_in(user)
group.add_developer(user) group.add_developer(user)
SystemNoteService.epic_issue(epic, issue, user, :added)
end end
context 'when issue note is returned' do context 'when issue note is returned' do
before do
SystemNoteService.epic_issue(epic, issue, user, :added)
end
shared_examples 'issue link presence' do shared_examples 'issue link presence' do
let(:issue) { create(:issue, project: project, description: "Project Issue") } let(:issue) { create(:issue, project: project, description: "Project Issue") }
...@@ -197,6 +200,15 @@ describe Groups::EpicsController do ...@@ -197,6 +200,15 @@ describe Groups::EpicsController do
end end
end end
end end
context 'setting notes filter' do
let(:issuable) { epic }
let(:issuable_parent) { group }
let!(:discussion_note) { create(:note, :system, noteable: issuable) }
let!(:discussion_comment) { create(:note, noteable: issuable) }
it_behaves_like 'issuable notes filter'
end
end end
describe 'GET #show' do describe 'GET #show' do
......
...@@ -1118,6 +1118,7 @@ describe Projects::IssuesController do ...@@ -1118,6 +1118,7 @@ describe Projects::IssuesController do
context 'when user is setting notes filters' do context 'when user is setting notes filters' do
let(:issuable) { issue } let(:issuable) { issue }
let(:issuable_parent) { project }
let!(:discussion_note) { create(:discussion_note_on_issue, :system, noteable: issuable, project: project) } let!(:discussion_note) { create(:discussion_note_on_issue, :system, noteable: issuable, project: project) }
it_behaves_like 'issuable notes filter' it_behaves_like 'issuable notes filter'
......
...@@ -78,6 +78,7 @@ describe Projects::MergeRequestsController do ...@@ -78,6 +78,7 @@ describe Projects::MergeRequestsController do
context 'when user is setting notes filters' do context 'when user is setting notes filters' do
let(:issuable) { merge_request } let(:issuable) { merge_request }
let(:issuable_parent) { project }
let!(:discussion_note) { create(:discussion_note_on_merge_request, :system, noteable: issuable, project: project) } let!(:discussion_note) { create(:discussion_note_on_merge_request, :system, noteable: issuable, project: project) }
let!(:discussion_comment) { create(:discussion_note_on_merge_request, noteable: issuable, project: project) } let!(:discussion_comment) { create(:discussion_note_on_merge_request, noteable: issuable, project: project) }
......
shared_examples 'issuable notes filter' do shared_examples 'issuable notes filter' do
let(:params) do
if issuable_parent.is_a?(Project)
{ namespace_id: issuable_parent.namespace, project_id: issuable_parent, id: issuable.iid }
else
{ group_id: issuable_parent, id: issuable.to_param }
end
end
it 'sets discussion filter' do it 'sets discussion filter' do
notes_filter = UserPreference::NOTES_FILTERS[:only_comments] notes_filter = UserPreference::NOTES_FILTERS[:only_comments]
get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issuable.iid, notes_filter: notes_filter } get :discussions, params: params.merge(notes_filter: notes_filter)
expect(user.reload.notes_filter_for(issuable)).to eq(notes_filter) expect(user.reload.notes_filter_for(issuable)).to eq(notes_filter)
expect(UserPreference.count).to eq(1) expect(UserPreference.count).to eq(1)
...@@ -13,7 +21,7 @@ shared_examples 'issuable notes filter' do ...@@ -13,7 +21,7 @@ shared_examples 'issuable notes filter' do
expect_any_instance_of(issuable.class).to receive(:expire_note_etag_cache) expect_any_instance_of(issuable.class).to receive(:expire_note_etag_cache)
get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issuable.iid, notes_filter: notes_filter } get :discussions, params: params.merge(notes_filter: notes_filter)
end end
it 'does not expires notes e-tag cache for issuable if filter did not change' do it 'does not expires notes e-tag cache for issuable if filter did not change' do
...@@ -22,14 +30,14 @@ shared_examples 'issuable notes filter' do ...@@ -22,14 +30,14 @@ shared_examples 'issuable notes filter' do
expect_any_instance_of(issuable.class).not_to receive(:expire_note_etag_cache) expect_any_instance_of(issuable.class).not_to receive(:expire_note_etag_cache)
get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issuable.iid, notes_filter: notes_filter } get :discussions, params: params.merge(notes_filter: notes_filter)
end end
it 'does not set notes filter when database is in read only mode' do it 'does not set notes filter when database is in read only mode' do
allow(Gitlab::Database).to receive(:read_only?).and_return(true) allow(Gitlab::Database).to receive(:read_only?).and_return(true)
notes_filter = UserPreference::NOTES_FILTERS[:only_comments] notes_filter = UserPreference::NOTES_FILTERS[:only_comments]
get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issuable.iid, notes_filter: notes_filter } get :discussions, params: params.merge(notes_filter: notes_filter)
expect(user.reload.notes_filter_for(issuable)).to eq(0) expect(user.reload.notes_filter_for(issuable)).to eq(0)
end end
...@@ -37,7 +45,7 @@ shared_examples 'issuable notes filter' do ...@@ -37,7 +45,7 @@ shared_examples 'issuable notes filter' do
it 'returns only user comments' do it 'returns only user comments' do
user.set_notes_filter(UserPreference::NOTES_FILTERS[:only_comments], issuable) user.set_notes_filter(UserPreference::NOTES_FILTERS[:only_comments], issuable)
get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issuable.iid } get :discussions, params: params
discussions = JSON.parse(response.body) discussions = JSON.parse(response.body)
expect(discussions.count).to eq(1) expect(discussions.count).to eq(1)
...@@ -47,7 +55,7 @@ shared_examples 'issuable notes filter' do ...@@ -47,7 +55,7 @@ shared_examples 'issuable notes filter' do
it 'returns only activity notes' do it 'returns only activity notes' do
user.set_notes_filter(UserPreference::NOTES_FILTERS[:only_activity], issuable) user.set_notes_filter(UserPreference::NOTES_FILTERS[:only_activity], issuable)
get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issuable.iid } get :discussions, params: params
discussions = JSON.parse(response.body) discussions = JSON.parse(response.body)
expect(discussions.count).to eq(1) expect(discussions.count).to eq(1)
...@@ -60,7 +68,7 @@ shared_examples 'issuable notes filter' do ...@@ -60,7 +68,7 @@ shared_examples 'issuable notes filter' do
expect(ResourceEvents::MergeIntoNotesService).not_to receive(:new) expect(ResourceEvents::MergeIntoNotesService).not_to receive(:new)
get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issuable.iid } get :discussions, params: params
end end
end end
end end
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